package com.za.plugin.transfer.form.insertupdate;

import com.za.plugin.util.SqlUtil;
import org.apache.ibatis.mapping.ParameterMapping;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * on duplicate key update 转为 merge into
 */
public class OnDuplicateKeyUpdateStyleTransfer implements StyleTransfer {
    @Override
    public boolean isSupport(String sql) {
        return sql.contains("on duplicate key update");
    }

    @Override
    public String transfer(String sql, String tableName, List<String> autoIncrProperties,
                           List<ParameterMapping> parameterMappingsCopy,
                           List<ParameterMapping> parameterMappings, Set<String> pKs, Map<String, List<String>> pkAndUniqueKeys) {
        List<String> keys = SqlUtil.getKeysFromParameterMappingsCopy(parameterMappingsCopy);
        Map<String, ParameterMapping> map = SqlUtil.getPropertyMapFromParameterMappings(parameterMappingsCopy);
        boolean isForEach = SqlUtil.isForEach(parameterMappingsCopy);

        if (isForEach && sql.contains("on duplicate key update")) {
            sql = "MERGE INTO " + SqlUtil.getTableName(tableName) + " o using (" + SqlUtil.strFromDualForEach(
                    keys, map, parameterMappings, sql, autoIncrProperties, parameterMappingsCopy, pKs) + " ) t on " + SqlUtil.onStr(pKs, keys, isForEach, autoIncrProperties, pkAndUniqueKeys, sql)
                    + " when matched then update set " + SqlUtil.setStrForEach(keys, pKs, autoIncrProperties, sql, pkAndUniqueKeys)
                    + " when not matched then insert " + SqlUtil.insertStrForEach(keys, pKs, sql, autoIncrProperties);

        }

        if (!isForEach && sql.contains("on duplicate key update")) {
            sql = "MERGE INTO " + SqlUtil.getTableName(tableName) + " o using (" + SqlUtil.strFromDualSimple(keys,
                    map, parameterMappings, sql, pKs, autoIncrProperties) + " ) t on " + SqlUtil.onStr(pKs, keys, isForEach, autoIncrProperties, pkAndUniqueKeys, sql)
                    + " when matched then update set " + SqlUtil.setStrSimple(keys, map, parameterMappings, pKs, sql, autoIncrProperties, pkAndUniqueKeys) +
                    " when not matched then insert " + SqlUtil.insertStrSimple(keys, map, parameterMappings, pKs, sql, autoIncrProperties);

        }

        return sql;
    }

}
